package cn.wlinker.video.monitor.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.system.SystemUtil;
import cn.wlinker.video.monitor.config.StaticFileConfig;
import lombok.SneakyThrows;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

/**
 * 服务url生成器
 *
 * @author gxsjx
 * @version 1.0
 * @date 2025/5/3
 * Copyright © wlinker.cn
 */
@Component
public class ServerUrlGenerator {

    @Resource
    private ServletWebServerApplicationContext serverContext;

    @Resource
    private Environment env;

    /**
     * 获取协议（http/https）
     *
     * @return
     */
    private String getProtocol() {
        return env.getProperty("server.ssl.key-store") != null ? "https" : "http";
    }

    /**
     * 获取外部访问地址
     *
     * @return
     */
    @SneakyThrows
    public String getExternalHost() {
        // 优先从配置读取，否则取服务器绑定地址
        String configHost = env.getProperty("server.external.host");
        if (StrUtil.isNotBlank(configHost)) {
            return configHost;
        }
        // 1. 获取当前请求的 ServletRequestAttributes
        ServletRequestAttributes attributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            // 2. 获取 HttpServletRequest 对象
            HttpServletRequest request = attributes.getRequest();
            // 3. 使用 Hutool 解析真实 IP
            return request.getServerName();
        }
        //非 Web 环境或异步线程中可能为空, 为空的条件下取本地IP地址
        return SystemUtil.getHostInfo().getAddress();
    }

    /**
     * 生成完整基础URL
     *
     * @return
     */
    public String generateBaseUrl() {
        String protocol = getProtocol();
        String host = getExternalHost();
        String port = StaticFileConfig.serverPort;
        String contextPath = Optional.ofNullable(StaticFileConfig.contextPath)
                .orElse("");
        return StrUtil.format("{}://{}:{}", protocol, host, port) + contextPath;
    }

    public String getVideoUrl(String streamId) {
        String baseUrl = generateBaseUrl();
        return StrUtil.format("{}/flv/live.flv?streamId={}", baseUrl, streamId);
    }
}